﻿using MoneyManagerNET.Presentation.ViewModel;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Windows.Input;
using MoneyManagerNET.Model;
using System.Collections.ObjectModel;
using System.ComponentModel;
using MoneyManagerNET.DAL.Mock;
using System.Linq;

namespace Tests.Presentation.ViewModel
{
    
    
    /// <summary>
    ///This is a test class for BankAccountViewModelTest and is intended
    ///to contain all BankAccountViewModelTest Unit Tests
    ///</summary>
    [TestClass()]
    public class BankAccountViewModelTest
    {

/// <summary>
/// 
/// 
/// </summary>
///// 

        Transaction CreateTransfer()
        {
            BankAccount acc1 = new BankAccount() { Name = "acc1" };
            BankAccount acc2 = new BankAccount() { Name = "acc2" };


            Category c = new Category() { Name = "categoriya" };
            SubCategory sc = new SubCategory() { Name = "alt categoriya", Category = c };

            Transaction tr = new Transaction()
            {
                FromAccount = acc1,
                ToAccount = acc2,
                Amount = 333,
                Category = c,
                SubCategory = sc
            };

            return tr;
        }


        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Additional test attributes
        // 
        //You can use the following additional attributes as you write your tests:
        //
        //Use ClassInitialize to run code before running the first test in the class
        //[ClassInitialize()]
        //public static void MyClassInitialize(TestContext testContext)
        //{
        //}
        //
        //Use ClassCleanup to run code after all tests in a class have run
        //[ClassCleanup()]
        //public static void MyClassCleanup()
        //{
        //}
        //
        //Use TestInitialize to run code before running each test
        //[TestInitialize()]
        //public void MyTestInitialize()
        //{
        //}
        //
        //Use TestCleanup to run code after each test has run
        //[TestCleanup()]
        //public void MyTestCleanup()
        //{
        //}
        //
        #endregion


        /// <summary>
        ///A test for BankAccountViewModel Constructor
        ///</summary>
        [TestMethod()]
        public void BankAccountViewModelConstructorTest()
        {
            BankAccountViewModel target = new BankAccountViewModel();
            Assert.Inconclusive("TODO: Implement code to verify target");
        }

        /// <summary>
        ///A test for DeleteCurrent
        ///</summary>
        [TestMethod()]
        public void DeleteCurrentTestSource()
        {
            var tran = CreateTransfer();
            var account = tran.FromAccount;


            BankAccountViewModel target = new BankAccountViewModel(); // TODO: Initialize to an appropriate value
            target.Model = account;
            target.Selected = tran;



            var srcCountWas = target.TransactionSource.Count;
            var toBeDeleted=target.Selected;
            toBeDeleted.Id=666;
            
            target.DeleteCurrent();

            var srcCountIs = target.TransactionSource.Count;

            Assert.AreEqual(srcCountWas - 1, srcCountIs, "src count ");
            
            var contains = target.TransactionSource.Contains(toBeDeleted);
            Assert.IsFalse(contains, "Deleted exists in list source cunt:{0}",target.TransactionSource.Count);



            target.Model = new BankAccount();
            target.Model = account;


            Assert.AreEqual(srcCountWas - 1, target.TransactionSource.Count, "src count ");

            contains = target.TransactionSource.Contains(toBeDeleted);
            Assert.IsFalse(contains, "Deleted exists in list source cunt:{0}", target.TransactionSource.Count);



        }



        /// <summary>
        ///A test for DeleteCurrent
        ///</summary>
        [TestMethod()]
        public void DeleteCurrentTestAccount()
        {
            var tran = CreateTransfer();
            var account = tran.FromAccount;


            BankAccountViewModel target = new BankAccountViewModel(); // TODO: Initialize to an appropriate value
            target.Model = account;
            target.Selected = tran;

            var countWas = account.GetAllTransactions().Count();


            var toBeDeleted = target.Selected;
            toBeDeleted.Id = 666;

            target.DeleteCurrent();



            var contains = target.TransactionSource.Contains(toBeDeleted);
            Assert.IsFalse(contains, "Deleted exists in list source cunt:{0}", target.TransactionSource.Count);


            var countIs = account.GetAllTransactions().Count();
            Assert.AreEqual(countWas - 1, account.GetAllTransactions().Count(), "account.GetAllTransactions count ");

            target.Model = new BankAccount();
            target.Model = account;


            Assert.AreEqual(countWas - 1, account.GetAllTransactions().Count(), "<-> account.GetAllTransactions count ");
            Assert.AreEqual(countWas - 1, target.ModelAs.GetAllTransactions().Count(), "<-> ModelAs.GetAllTransactions count ");




            contains = target.TransactionSource.Contains(toBeDeleted);
            Assert.IsFalse(contains, "Deleted exists in list source cunt:{0}", target.TransactionSource.Count);



        }



        /// <summary>
        ///A test for PromptForEditCurrent
        ///</summary>
        [TestMethod()]
        public void PromptForEditCurrentTest()
        {
            BankAccountViewModel target = new BankAccountViewModel(); // TODO: Initialize to an appropriate value
            object o = null; // TODO: Initialize to an appropriate value
            target.PromptForEditCurrent(o);
            Assert.Inconclusive("A method that does not return a value cannot be verified.");
        }

        /// <summary>
        ///A test for PromptForNew
        ///</summary>
        [TestMethod()]
        public void PromptForNewTest()
        {
            BankAccountViewModel target = new BankAccountViewModel(); // TODO: Initialize to an appropriate value
            object o = null; // TODO: Initialize to an appropriate value
            target.PromptForNew(o);
            Assert.Inconclusive("A method that does not return a value cannot be verified.");
        }

        /// <summary>
        ///A test for AccountBalance
        ///</summary>
        [TestMethod()]
        public void AccountBalanceTest()
        {
            BankAccountViewModel target = new BankAccountViewModel(); // TODO: Initialize to an appropriate value
            Decimal actual;
            actual = target.AccountBalance;
            Assert.Inconclusive("Verify the correctness of this test method.");
        }

        /// <summary>
        ///A test for DeleteCommand
        ///</summary>
        [TestMethod()]
        [DeploymentItem("MoneyManagerNET.Presentation.ViewModel.dll")]
        public void DeleteCommandTest()
        {
            BankAccountViewModel_Accessor target = new BankAccountViewModel_Accessor(); // TODO: Initialize to an appropriate value
            ICommand expected = null; // TODO: Initialize to an appropriate value
            ICommand actual;
            target.DeleteCommand = expected;
            actual = target.DeleteCommand;
            Assert.AreEqual(expected, actual);
            Assert.Inconclusive("Verify the correctness of this test method.");
        }

        /// <summary>
        ///A test for EditCommand
        ///</summary>
        [TestMethod()]
        [DeploymentItem("MoneyManagerNET.Presentation.ViewModel.dll")]
        public void EditCommandTest()
        {
            BankAccountViewModel_Accessor target = new BankAccountViewModel_Accessor(); // TODO: Initialize to an appropriate value
            ICommand expected = null; // TODO: Initialize to an appropriate value
            ICommand actual;
            target.EditCommand = expected;
            actual = target.EditCommand;
            Assert.AreEqual(expected, actual);
            Assert.Inconclusive("Verify the correctness of this test method.");
        }

        /// <summary>
        ///A test for Filter
        ///</summary>
        [TestMethod()]
        public void FilterTest()
        {
            BankAccountViewModel target = new BankAccountViewModel(); // TODO: Initialize to an appropriate value
            BankAccountViewModel.TransactionFilter expected = null; // TODO: Initialize to an appropriate value
            BankAccountViewModel.TransactionFilter actual;
            target.Filter = expected;
            actual = target.Filter;
            Assert.AreEqual(expected, actual);
            Assert.Inconclusive("Verify the correctness of this test method.");
        }

        /// <summary>
        ///A test for FilterList
        ///</summary>
        [TestMethod()]
        public void FilterListTest()
        {
            BankAccountViewModel target = new BankAccountViewModel(); // TODO: Initialize to an appropriate value
            BankAccountViewModel.TransactionFilter[] actual;
            actual = target.FilterList;
            Assert.Inconclusive("Verify the correctness of this test method.");
        }

        /// <summary>
        ///A test for Model
        ///</summary>
        [TestMethod()]
        public void ModelTest()
        {
            BankAccountViewModel target = new BankAccountViewModel(); // TODO: Initialize to an appropriate value
            object expected = null; // TODO: Initialize to an appropriate value
            object actual;
            target.Model = expected;
            actual = target.Model;
            Assert.AreEqual(expected, actual);
            Assert.Inconclusive("Verify the correctness of this test method.");
        }

        /// <summary>
        ///A test for Name
        ///</summary>
        [TestMethod()]
        public void NameTest()
        {
            BankAccountViewModel target = new BankAccountViewModel(); // TODO: Initialize to an appropriate value
            string actual;
            actual = target.Name;
            Assert.Inconclusive("Verify the correctness of this test method.");
        }

        /// <summary>
        ///A test for NewCommand
        ///</summary>
        [TestMethod()]
        [DeploymentItem("MoneyManagerNET.Presentation.ViewModel.dll")]
        public void NewCommandTest()
        {
            BankAccountViewModel_Accessor target = new BankAccountViewModel_Accessor(); // TODO: Initialize to an appropriate value
            ICommand expected = null; // TODO: Initialize to an appropriate value
            ICommand actual;
            target.NewCommand = expected;
            actual = target.NewCommand;
            Assert.AreEqual(expected, actual);
            Assert.Inconclusive("Verify the correctness of this test method.");
        }

        /// <summary>
        ///A test for ReconciledBalance
        ///</summary>
        [TestMethod()]
        public void ReconciledBalanceTest()
        {
            var vm = new BankAccountViewModel();

            bool notified=false;
            vm.PropertyChanged += (o, e) => { if (e.PropertyName == "ReconciledBalance") notified = true; };

            var prevRecBalance=vm.ReconciledBalance;


            var account = MoneyManagerNET.App.Storage.New<IBankAccount>();
            account.Name = "Purse";
            account.Balance = 100;
            vm.ModelAs = account;

            Assert.IsTrue(notified, "vm should notify ReconciledBalance change when model changes");
            Assert.AreEqual(account.GetReconciledBalance(), vm.ReconciledBalance," reconciled balance ");



            var tran = MoneyManagerNET.App.Storage.New<ITransaction>();
            tran.ToAccount = account;
            tran.Status =(byte) TransactionStatus.Reconciled;
            tran.Amount = 30;
            Assert.AreEqual(account.GetReconciledBalance(), 130, "reconciled transaction should inc/dec reconciled balance");

            tran.ToAccount = null;
            tran.FromAccount = account;
            tran.Amount = 30;
            Assert.AreEqual(account.GetReconciledBalance(), 70, "reconciled transaction should inc/dec reconciled balance");


        }

        /// <summary>
        ///A test for Selected
        ///</summary>
        [TestMethod()]
        public void SelectedTest()
        {
            BankAccountViewModel target = new BankAccountViewModel(); // TODO: Initialize to an appropriate value
            ITransaction actual;
            actual = target.Selected;
            Assert.Inconclusive("Verify the correctness of this test method.");
        }

        /// <summary>
        ///A test for TransactionSource
        ///</summary>
        [TestMethod()]
        public void TransactionSourceTest()
        {
            BankAccountViewModel target = new BankAccountViewModel(); // TODO: Initialize to an appropriate value
            ObservableCollection<ITransaction> expected = null; // TODO: Initialize to an appropriate value
            ObservableCollection<ITransaction> actual;
            target.TransactionSource = expected;
            actual = target.TransactionSource;
            Assert.AreEqual(expected, actual);
            Assert.Inconclusive("Verify the correctness of this test method.");
        }

        /// <summary>
        ///A test for Transactions
        ///</summary>
        [TestMethod()]
        [DeploymentItem("MoneyManagerNET.Presentation.ViewModel.dll")]
        public void TransactionsTest()
        {
            BankAccount acc1 = new BankAccount() { Name = "acc1" };


            for (int i = 0; i < 12; i++)
            {
                Transaction tran = new Transaction()
                {
                    FromAccount = acc1,
                    Amount = 4
                };
            }

            for (int i = 0; i < 12; i++)
            {
                Transaction tran = new Transaction()
                {
                    ToAccount = acc1,
                    Amount = 100
                };
            }


            BankAccountViewModel accvm = new BankAccountViewModel();
            BankAccountViewModel_Accessor target = new BankAccountViewModel_Accessor(); // TODO: Initialize to an appropriate value
            ICollectionView expected = null; // TODO: Initialize to an appropriate value
            ICollectionView actual;
            target.Transactions = expected;
            actual = target.Transactions;
            Assert.AreEqual(expected, actual);
            Assert.Inconclusive("Verify the correctness of this test method.");
        }
    }
}
